package gpl.scotlandyard.beans.adapters;

import gpl.scotlandyard.beans.basics.Link;
import gpl.scotlandyard.beans.basics.Node;
import gpl.scotlandyard.beans.basics.Player;
import gpl.scotlandyard.beans.basics.Ticket;
import gpl.scotlandyard.utils.Config;
import gpl.scotlandyard.utils.I18n;

import java.util.ArrayList;
import java.util.List;

import javax.swing.table.AbstractTableModel;

/**
 * Reprensents a tracing table. Shows location and ticket used to reached this
 * one.
 * 
 * @author Norbert Martin
 */
public class PlayerMovesTM extends AbstractTableModel {

  private static final long serialVersionUID = 1L;

  private static final List<Integer> STEPS = new ArrayList<Integer>();
  static {
    for (String s : Config.get("STEPS").split(",")) {
      STEPS.add(Integer.parseInt(s));
    }
  }
  private static final int NUM_COLUMNS = 2;

  private final Player player;

  private boolean showAll;

  /**
   * Creates a tracer TM.
   * 
   * @param p
   */
  public PlayerMovesTM(Player p) {
    p.getClass();
    this.player = p;
    p.addListener(new Player.ListenerImpl() {
      @Override
      public void playerMoved(Player p, Link l) {
        if (player.equals(p)) {
          fireTableDataChanged();
        }
      }
    });
  }

  @Override
  public int getColumnCount() {
    return NUM_COLUMNS;
  }

  @Override
  public int getRowCount() {
    return player.getPrevMoves().size();
  }

  @Override
  public Object getValueAt(int rowIndex, int columnIndex) {
    if (columnIndex == 0) {
      return getNodeOnTurn(rowIndex);
    }
    if (columnIndex == 1) {
      return I18n.get(getTicketOnTurn(rowIndex).toString());
    }
    throw new IndexOutOfBoundsException();
  }

  @Override
  public String getColumnName(int column) {
    if (column == 0) {
      return I18n.get("LOCATION");
    }
    if (column == 1) {
      return I18n.get("TICKET");
    }
    throw new IndexOutOfBoundsException();
  }

  /**
   * Shows all moves without filtered turns and hide tickets.
   * 
   * @param b
   */
  public void showAll(boolean b) {
    showAll = b;
    fireTableDataChanged();
  }

  /**
   * Returns the player name.
   * 
   * @return name
   */
  public String getName() {
    return player.getName();
  }

  /**
   * Returns ticket used for turn i. Gets hidden tickets if show all is set to
   * true.
   * 
   * @param i
   * @return ticket for this turn
   */
  private Ticket getTicketOnTurn(int i) {
    if (showAll) {
      return player.getPrevMoves().get(i).getHiddenTicket() != null ? player.getPrevMoves().get(i).getHiddenTicket() : player
          .getPrevMoves().get(i).getTicket();
    }
    return player.getPrevMoves().get(i).getTicket();
  }

  /**
   * Returns node for turn i. Nodes are hidden if player is fugitive and turn is
   * not a visible turn. Shows all if show all is set to true.
   * 
   * @param i
   * @return node for this turn
   */
  private Node getNodeOnTurn(int i) {
    if (showAll || !player.isFugitive()) {
      return player.getPrevMoves().get(i).getToNode();
    }
    if (STEPS.contains(i)) {
      return player.getPrevMoves().get(i).getToNode();
    }
    return Node.getUnknownNode();

  }
}
